package logic

import (
	"context"
	"strings"
	"time"

	"mall/common/globalkey"
	"mall/service/mqueue/job/internal/svc"

	"github.com/hibiken/asynq"
	"github.com/zeromicro/go-zero/core/logx"
)

type ScanUpdatedGorseCacheProcessor struct {
	svcCtx *svc.ServiceContext
}

func NewScanUpdatedGorseCacheProcessor(svcCtx *svc.ServiceContext) *ScanUpdatedGorseCacheProcessor {
	return &ScanUpdatedGorseCacheProcessor{
		svcCtx: svcCtx,
	}
}

/*
LastTimeChink:1  =  2025-04-16:0	未点击，三天一更
LastTimeChink:1  =  2025-04-16:1	已点击，一天一更
解释: LastTimeChink:用户ID  =  更新时间:点击状态

ItemLastTimeChick:1  =  "1,2,3,4"	最新
ItemPopularCache:1  =  "1,2,3,4"	热门
解释: LastTimeChink:用户ID  =  itemID
*/

// 定时更新gorse推荐系统缓存  被动更新,每天凌晨00:10执行
func (l *ScanUpdatedGorseCacheProcessor) ProcessTask(ctx context.Context, t *asynq.Task) error {
	now := time.Now()
	key := globalkey.ItemLastTimeChick
	//查询以 `LastTimeChink:` 开头的key
	keys, err := l.svcCtx.BizRedis.KeysCtx(ctx, key+"*")
	if err != nil {
		return err
	}

	var pids []string
	var idMap = make(map[string]struct{})
	if len(keys) > 0 {
		for _, v := range keys {
			//v=LastTimeChink:1
			if len(strings.TrimSpace(v)) > 0 {
				var pid string
				split := strings.Split(v, ":")
				if len(split) == 2 {
					if len(strings.TrimSpace(split[1])) > 0 {
						pid = strings.TrimSpace(split[1])
					}
				}
				if len(strings.TrimSpace(pid)) == 0 {
					continue
				}

				//lastTimeValue=2025-03-14:1  or  lastTimeValue=2025-03-14:0
				lastTimeValue, err := l.svcCtx.BizRedis.GetCtx(ctx, v)
				if err != nil || len(strings.TrimSpace(lastTimeValue)) == 0 {
					continue
				}

				lastTimeValues := strings.Split(lastTimeValue, ":")

				if len(lastTimeValues) == 2 {
					updateTime := lastTimeValues[0]
					isChink := lastTimeValues[1]
					if len(strings.TrimSpace(isChink)) > 0 && len(strings.TrimSpace(updateTime)) > 0 {
						lTime, err := time.Parse("2006-01-02", updateTime)
						if err != nil {
							if _, ok := idMap[pid]; !ok {
								idMap[pid] = struct{}{}
								pids = append(pids, pid)
							}
							continue
						}
						nowTime, err := time.Parse("2006-01-02", now.Format("2006-01-02"))
						if err != nil {
							if _, ok := idMap[pid]; !ok {
								idMap[pid] = struct{}{}
								pids = append(pids, pid)
							}
							continue
						}
						timeDifference := int(nowTime.Sub(lTime).Hours() / 24)
						//未点击
						if isChink == "0" && timeDifference >= 3 {
							if _, ok := idMap[pid]; !ok {
								idMap[pid] = struct{}{}
								pids = append(pids, pid)
							}
						}
						//已点击
						if isChink == "1" && timeDifference >= 1 {
							if _, ok := idMap[pid]; !ok {
								idMap[pid] = struct{}{}
								pids = append(pids, pid)
							}
						}
					}
				}
			}
		}
	}

	//查询推荐系统并更新
	if len(pids) > 0 {
		for _, v := range pids {
			whitUpdateTime := false
			//更新缓存
			popularIds := l.getItemPopular(v)
			if len(popularIds) > 0 {
				// key = ItemLastTimeChick:1 (ItemLastTimeChick:用户id)
				// value = 2025-04-15:1 (更新时间:点击状态)
				err := l.svcCtx.BizRedis.SetCtx(ctx, globalkey.ItemPopularCache+v, strings.Join(popularIds, ","))
				if err != nil {
					logx.Errorf("getItemPopular SetCtx Error: %+v", err)
					return err
				}
				whitUpdateTime = true
			}

			latestIds := l.getItemLatest(v)
			if len(latestIds) > 0 {
				err := l.svcCtx.BizRedis.SetCtx(ctx, globalkey.ItemLatestCache+v, strings.Join(latestIds, ","))
				if err != nil {
					logx.Errorf("getItemLatest SetCtx Error: %+v", err)
					return err
				}
				whitUpdateTime = true
			}

			if whitUpdateTime {
				err := l.svcCtx.BizRedis.SetCtx(ctx, key+v, now.Format("2006-01-02")+":"+"0")
				if err != nil {
					logx.Errorf("GetItemPopular SetCtx Error: %+v", err)
					return err
				}
			}
		}
	}

	return nil
}

func (l *ScanUpdatedGorseCacheProcessor) getItemPopular(pid string) []string {
	var forumPostIds []string
	res, err := l.svcCtx.GorseClient.GetItemPopular(
		l.svcCtx.Config.GorseUrl, pid, "0", "0",
	)
	if err != nil {
		logx.Errorf("getItemPopular GorseClient.GetItemPopular Error: %+v", err)
		return nil
	}
	if res != nil && len(res) > 0 {
		if list, ok := res["list"]; ok {
			for _, v := range list.([]any) {
				if id, iOk := v.(map[string]any)["id"]; iOk {
					forumPostIds = append(forumPostIds, id.(string))
				}
			}
		}
	}
	return forumPostIds
}

func (l *ScanUpdatedGorseCacheProcessor) getItemLatest(pid string) []string {
	var forumPostIds []string
	res, err := l.svcCtx.GorseClient.GetItemLatest(
		l.svcCtx.Config.GorseUrl, pid, "0", "0",
	)
	if err != nil {
		logx.Errorf("getItemLatest GorseClient.GetItemLatest Error: %+v", err)
		return nil
	}
	if res != nil && len(res) > 0 {
		if list, ok := res["list"]; ok {
			for _, v := range list.([]any) {
				if id, iOk := v.(map[string]any)["id"]; iOk {
					forumPostIds = append(forumPostIds, id.(string))
				}
			}
		}
	}
	return forumPostIds
}
